package com.inspur.edp.bef.bizentity.json.operation;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.inspur.edp.bef.bizentity.common.BizEntityJsonConst;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.operation.componentbase.BizParActualValue;
import com.inspur.edp.bef.bizentity.operation.componentbase.BizParameter;
import com.inspur.edp.bef.bizentity.operation.componentenum.BizCollectionParameterType;
import com.inspur.edp.bef.bizentity.operation.componentenum.BizParameterMode;
import com.inspur.edp.bef.bizentity.operation.componentenum.BizParameterType;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;

import java.io.IOException;

import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;

public abstract class BizParaDeserializer<T extends BizParameter> extends JsonDeserializer<T> {
    @Override
    public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
        return deserializePara(jsonParser);
    }

    public final T deserializePara(JsonParser jsonParser) {
        T op = createBizPara();
        op.setParamDescription("");
        op.setParamCode("");
        op.setParamName("");
        SerializerUtils.readStartObject(jsonParser);
        while (jsonParser.getCurrentToken() == FIELD_NAME) {
            String propName = SerializerUtils.readPropertyName(jsonParser);
            readPropertyValue(op, propName, jsonParser);
        }
        SerializerUtils.readEndObject(jsonParser);
        return op;
    }

    private void readPropertyValue(BizParameter para, String propName, JsonParser jsonParser) {
        switch (propName) {
            case CommonModelNames.ID:
                para.setID(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.ParamCode:
                para.setParamCode(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.ParamName:
                para.setParamName(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.ParameterType:
                para.setParameterType(SerializerUtils.readPropertyValue_Enum(jsonParser, BizParameterType.class, BizParameterType.values()));
                break;
            case BizEntityJsonConst.Assembly:
                para.setAssembly(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.ClassName:
                para.setNetClassName(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.JavaClassName:
                para.setClassName(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.Mode:
                para.setMode(SerializerUtils.readPropertyValue_Enum(jsonParser, BizParameterMode.class, BizParameterMode.values()));
                break;
            case BizEntityJsonConst.ParamDescription:
                para.setParamDescription(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case BizEntityJsonConst.CollectionParameterType:
                para.setCollectionParameterType(SerializerUtils.readPropertyValue_Enum(jsonParser, BizCollectionParameterType.class, BizCollectionParameterType.values()));
                break;
            case BizEntityJsonConst.ParamActualValue:
                if(SerializerUtils.readNullObject(jsonParser)){
                    return;
                }
                para.setActualValue(SerializerUtils.readPropertyValue_Object(BizParActualValue.class, jsonParser));
                //TODO: ?????? 此处参考了CustomizationInfo的反序列化, 有进一步完善的空间
                try {
                    jsonParser.nextToken();
                } catch (IOException e) {
                    throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0003, e);
                }
                break;
            case BizEntityJsonConst.IsVoidReturnType:
                para.setVoidReturnType(SerializerUtils.readPropertyValue_boolean(jsonParser));
                break;
            default:
                if (!readExtendParaProperty(para, propName, jsonParser)) {
                    throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0064, "BizOperationDeserializer", propName);
                }
        }
    }

    protected boolean readExtendParaProperty(BizParameter op, String propName, JsonParser jsonParser) {
        return false;
    }

    protected abstract T createBizPara();

}
